package de.eridea.learning.java.usermanagement.persistence;

import java.util.Set;

public interface UserManager {

	/**
	 * Retrieve a user
	 * 
	 * @param loginName
	 *            The login name to look up.
	 * @return the persistent user object with the specified login name, or null
	 *         if no matching entry was found.
	 */
	public User getUser(String loginName);

	/**
	 * Check whether a name (or any string value) is in use.
	 * 
	 * @param entity
	 *            The class on which to look up.
	 * @param field
	 *            The name of the field in which to look for <code>value</code>.
	 * @param value
	 *            The string value to look for.
	 * @return <code>true</code>, if an entry of class <code>entity</code>, on
	 *         which the field <code>field</code> has a value of
	 *         <code>value</code>, exists; <code>false</code> otherwise.
	 */
	public boolean nameExists(Class entity, String field, String value);

	/**
	 * Update the database to reflect changes made to a user object.
	 * 
	 * @param user
	 *            The persistent user object to update.
	 */
	public void updateUser(User user);

	/**
	 * Create and return a new object of the class used to represent users.
	 * 
	 * Used to get a new user object which can be configured and persisted.
	 * 
	 * @return the new user object.
	 */
	public User createUserObject();

	/**
	 * Make a user persistent.
	 * 
	 * @param user
	 *            The user object to persist.
	 */
	public void persistUser(User user);

	/**
	 * Retrieve a group.
	 * 
	 * @param groupName
	 *            The group name to look up.
	 * @return the persistent group object with the specified name, or null if
	 *         no matching entry was found.
	 */
	public Group getGroup(String groupName);

	/**
	 * Update the database to reflect changes made to a group object.
	 * 
	 * @param group
	 *            The persistent group object to update.
	 */
	public void updateGroup(Group group);

	/**
	 * Create and return a new object of the class used to represent groups.
	 * 
	 * Used to get a new group object which can be configured and persisted.
	 * 
	 * @return the new group object.
	 */
	public Group createGroupObject();

	/**
	 * Make a group persistent.
	 * 
	 * @param group
	 *            The group object to persist.
	 */
	public void persistGroup(Group group);

	/**
	 * Retrieve a resource.
	 * 
	 * @param resourceIdentifier
	 *            The resource identifier to look up.
	 * @return the persistent resource object with the specified identifier, or
	 *         null if no matching entry was found.
	 */
	public Resource getResource(String resourceIdentifier);

	/**
	 * Update the database to reflect changes made to a resource object.
	 * 
	 * @param resource
	 *            The persistent resource object to update.
	 */
	public void updateResource(Resource resource);

	/**
	 * Create and return a new object of the class used to represent resources.
	 * 
	 * Used to get a new resource object which can be configured and persisted.
	 * 
	 * @return the new resource object.
	 */
	public Resource createResourceObject();

	/**
	 * Make a resource persistent.
	 * 
	 * @param resource
	 *            The resource object to persist.
	 */
	public void persistResource(Resource resource);

	/**
	 * Check whether a specific user is in a specific group.
	 * 
	 * @param user
	 *            The user to look up.
	 * @param group
	 *            The group to look up.
	 * @return <code>true</code> if <code>user</code> is in <code>group</code>,
	 *         false otherwise.
	 */
	public boolean isUserInGroup(User user, Group group);

	/**
	 * Check whether a specific user is in a specific group.
	 * 
	 * @param userName
	 *            The login name of the user to look up.
	 * @param groupName
	 *            The name of the group to look up.
	 * @return <code>true</code> if user <code>user</code> is in group
	 *         <code>group</code>, false otherwise.
	 */
	public boolean isUserInGroup(String userName, String groupName);

	/**
	 * Add a specific user to a specific group.
	 * 
	 * @param user
	 *            The user to add.
	 * @param group
	 *            The group to add <code>user</code> to.
	 * @return <code>true</code> if the operation was completed;
	 *         <code>false</code> if <code>user</code> already was in
	 *         <code>group</code>.
	 */
	public boolean addUserToGroup(User user, Group group);

	/**
	 * Add a specific user to a specific group.
	 * 
	 * @param userName
	 *            The login name of the user to add.
	 * @param groupName
	 *            The name of the group to add the user to.
	 * @return <code>true</code> if the operation was completed;
	 *         <code>false</code> if the user already was in the group.
	 */
	public boolean addUserToGroup(String userName, String groupName);

	/**
	 * Remove a specific user from a specific group.
	 * 
	 * @param user
	 *            The user to remove.
	 * @param group
	 *            The group to remove <code>user</code> from.
	 * @return <code>true</code> if the operation was completed,
	 *         <code>false</code> if <code>user</code> was not in
	 *         <code>group</code> before the method was called.
	 */
	public boolean removeUserFromGroup(User user, Group group);

	/**
	 * Remove a specific user from a specific group.
	 * 
	 * @param userName
	 *            The name of the user to remove.
	 * @param groupName
	 *            The name of the group to remove the user from.
	 * @return <code>true</code> if the operation was completed,
	 *         <code>false</code> if the user was not in the group before the
	 *         method was called.
	 */
	public boolean removeUserFromGroup(String userName, String groupName);

	/**
	 * Test whether a group has permission to access a resource.
	 * 
	 * @param group
	 *            The group to look up.
	 * @param resource
	 *            The resource to look up.
	 * @return <code>true</code> if permission is granted to the group,
	 *         <code>false</code> otherwise.
	 */
	public boolean isPermittedGroupForResource(Group group, Resource resource);

	/**
	 * Grant a group permission to access a resource.
	 * 
	 * @param group
	 * @param resource
	 * @return <code>true</code> if the operation was completed,
	 *         <code>false</code> if the group already was permitted to access
	 *         the resource.
	 */
	public boolean grantPermission(String group, String resource);

	/**
	 * Revoke a group’s permission to access a resource.
	 * 
	 * @param group
	 * @param resource
	 * @return <code>true</code> if the operation was completed,
	 *         <code>false</code> if the group didn’t have permission to access
	 *         the resource before the method was invoked.
	 */
	public boolean revokePermission(String group, String resource);

	/**
	 * Tests whether a user is in any of the groups which are permitted to
	 * access a resource.
	 * 
	 * @param user
	 * @param resource
	 * @return <code>true</code> if there exists a group in which
	 *         <code>user</code> is and which is granted permission to access
	 *         <code>resource</code>.
	 */
	public boolean isUserInPermittedGroupForResource(String user,
			String resource);

	/**
	 * Retrieve all groups.
	 * @return the set of all registered groups.
	 */
	public Set<Group> getGroups();

}
